package chase.myrewards;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.http.*;
import com.google.appengine.api.rdbms.AppEngineDriver;
import com.google.appengine.api.utils.SystemProperty;
import chase.myrewards.beans.Customer;

/**
 * Servlet that takes app password as input and returns the CustomerID
 * 
 * @author Archi Pandurangi
 * @date April 24, 2013
 * 
 */
public class AppLoginServlet extends HttpServlet implements Serializable {

	/**
	 * This number must be unique for every class. And it can never change.
	 * You have to generate it automatically by clicking on the class name and
	 * then hitting Ctrl+1.  Then click on Add generated serial version ID. Then
	 * copy these comments on top of the generated id.
	 * 
	 * @serial serialVersionUID
	 */
	private static final long serialVersionUID = 1526206868239571747L;

	private static final Logger log = Logger.getLogger(AppLoginServlet.class.getName());
	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		Customer cust = null;
		log.info("Session Id is " + request.getSession().getId());

		// The app is running on App Engine
		if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {	
			Connection c = null;
			try {
				DriverManager.registerDriver(new AppEngineDriver());
				c = DriverManager.getConnection("jdbc:google:rdbms://myrewards2013:myrewardsdatabase/myrewards");
				
				// Getting the entered password from the app
				String password = request.getParameter("password");

				// Getting the corresponding Customer from setting table
				java.sql.Statement stmt =  c.createStatement();
				java.sql.ResultSet rs = stmt.executeQuery(Queries.CUSTOMER(password));

				// If the result set is not empty, then create a Customer bean.
				// Otherwise, cust is null and null will be returned to the client.
				if(rs.next()){
					cust = new Customer();
					
					// Put all the settings in customer bean
					cust.setCustomerID(rs.getString("customer_id"));
					cust.setPassword(rs.getString("password"));
					cust.setShowLocations(rs.getBoolean("show_locations"));
					cust.setFavorites(rs.getBoolean("show_favorites"));
					cust.setRecent(rs.getBoolean("show_recent"));

					// Set the customer object for the session
					HttpSession session = request.getSession();
					session.setAttribute("customer", cust);

					// Serializing the data in the bean and sending back to client	
					try {
						response.setContentType("application/octet-stream");
						ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
						out.writeObject(cust);
						out.flush();
						out.close();
					}
					catch(IOException i){
						log.log(Level.SEVERE, "IOException", i);
					}
				}
				else{
					log.info("There is not customer for password " + password);
				}
			}
			catch (SQLException e) {
				log.log(Level.SEVERE, "SQLException", e);
			} 
			finally {
				if (c != null){ 
					try {
						c.close();
					} 
					catch (SQLException ignore) {}
				}
			}
		}

		
		// Running on development server
		else {
			cust = new Customer();
			cust.setCustomerID("4321679052"); // putting this in the bean..set this value manually for testing
			cust.setPassword("ABX66XBA7QJ");
			cust.setShowLocations(true);
			cust.setFavorites(false);
			cust.setRecent(true);
			
			// Set the customer object for the session
			HttpSession session = request.getSession();
			session.setAttribute("customer", cust);
			
			// Serializing the data in the bean and sending back to client	
			try {
				response.setContentType("application/octet-stream");
				ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
				out.writeObject(cust);
				out.flush();
				out.close();
			}
			catch(IOException i){
				log.log(Level.SEVERE, "IOException", i);
			}
		}
		
		return;
	}
}
